#include "thread.hpp"
#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include "LockGuard.hpp"
template<class T = void>
void Print(T data)
{
    while(data--)
    {
        std::cout<<"TID:"<<pthread_self()<<","<<"I am a Thread Task\n";
        sleep(1);
    }
}

int Ticket = 10000;



//为了解决这个多线程的问题，就需要锁来限制多个线程同时访
//1.把并行访问变成串行访问
//2.一般加锁，给临界区加锁。申请锁是安全的。
//3.锁是由程序员实现代码时来保证的
//4.


//下面是一个全局的锁,对线程而言也是共享资源
//那么申请所是原子的吗？如果不是原子的，不是也不安全吗？
//答案是安全的。
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

//在下面多线程显示过程，
//由于函数的可重入，导致票被抢到了负数
void GetTicket(pthread_mutex_t* mutex)
{
    while(1)
    {
        //使用这种代码块的方式，用锁的局部方法可以很好的解决这个问题
        {
            LockGuard Test_Mutex(mutex);
            if (Ticket > 0)
            {
                usleep(1);
                std::cout<<"get a ticket\n"<<"Ticket rest:"<<--Ticket<<"\n";
                
            }
            else
            {
                break;
            }
        }











        //原生局部锁测试
        // //从这里之后的代码，便会上锁
        // pthread_mutex_lock(mutex);
        // if(Ticket>0)
        // {
        //     usleep(1);
        //     std::cout<<"get a ticket\n"<<"Ticket rest:"<<Ticket<<"\n";
        //     Ticket--;
        //     pthread_mutex_unlock(mutex);
        // }
        // else
        // {
        //     pthread_mutex_unlock(mutex);
        //     break;
        // }
        // //可以在此处解锁吗？
        // //不行，因为一旦走了break，会导致没有解锁
        // // pthread_mutex_unlock(&mutex);
    } 
}


int main()
{

    //局部上锁
    pthread_mutex_t locale_mutex;
    pthread_mutex_init(&locale_mutex,nullptr);



    std::string name = " <:customer:";
    std::vector<fuh::thread<pthread_mutex_t*>> Customers;
    for(int i = 0;i<5;i++)
    {
        name = " <:customer:"+ fuh::GetThreadName();
        Customers.push_back(fuh::thread<pthread_mutex_t*>(GetTicket,&locale_mutex));
    }
    for(auto &td:Customers)
    {
        td.Start();
    }
    for(auto &td:Customers)
    {
        td.join();
    }

    pthread_mutex_destroy(&locale_mutex);

    //测试模板类实现的线程
    // int a = 10;
    // fuh::thread<int> t (Print<int>,a);
    // t.Start();
    // t.join();

    //-----测试多个线程
    // std::vector<fuh::thread> threads;
    // const int num = 5;
    // for(int i = 0;i<num;i++)
    // {
    //     threads.push_back(fuh::thread(Print)); 
    // }

    // for(auto &td:threads){
    //     td.Start();
    //     std::cout<<"Is "<< td.TName()<< "Runing?::"<<std::boolalpha<<td.Isrunning()<<"\n";
    // }
    //  for(auto &td:threads){
    //     td.join();
    // }
    // // fuh::thread t(Print);  
    // // std::cout<<"Is thread Runing?::"<<std::boolalpha<<t.Isrunning()<<"\n";
    // // t.Start();
    // // std::cout<<"Is thread Runing?::"<<std::boolalpha<<t.Isrunning()<<"\n";
    // // t.join();
    return 0;
}